﻿using System.Collections.Generic;
using System.IO;
using System.Reflection;
using GeoAPI.CoordinateSystems;
using ProjNet.CoordinateSystems;
using SharpMap.Converters.WellKnownText;

namespace AzukiMap.Tools
{
    public static class SridParser
    {
        private static readonly Dictionary<int, ICoordinateSystem> CoordSystemCache = new Dictionary<int, ICoordinateSystem>();

        public static ICoordinateSystem GetCoordinateSystemFromSrid(int srid)
        {
            if ( CoordSystemCache.ContainsKey(srid) )
            {
                return CoordSystemCache[srid];
            }

            string wkt = GetProjectionWKT(srid);

            var cs = (ICoordinateSystem) CoordinateSystemWktReader.Parse(wkt);
            CoordSystemCache.Add(srid, cs);

            return cs;
        }

        public static string GetProjectionWKT(int srid)
        {
            Assembly assm = Assembly.GetExecutingAssembly();
            string projectName = assm.FullName.Split(new char[]{','})[0];
            //string projectName = assm.GetName().Name;
            Stream s = assm.GetManifestResourceStream(projectName + ".resources.srid.csv");
            TextReader reader = new StreamReader(s);

            string l;
            var splitter = new char[1];
            splitter[0] = ';';
            while ((l = reader.ReadLine()) != null)
            {
                string[] line = l.Split(splitter);
                if (srid.ToString() == line[0])
                {
                    return line[1];
                }
            }
            return "";
        }

        public static double GetInchesPerUnit(int srid)
        {
            double inchesPerUnit = 0.0;
            ICoordinateSystem cs = GetCoordinateSystemFromSrid(srid);
            var csInfo = (Info) cs.GetUnits(0);

            if (csInfo.GetType() == typeof (LinearUnit))
            {
                double metersPerUnit = ((LinearUnit) csInfo).MetersPerUnit;
                inchesPerUnit = metersPerUnit * AzukiMapSettings.INCHES_PER_METER;
            }
            if (csInfo.GetType() == typeof (AngularUnit))
            {
                //double radiansPerUnit = ((AngularUnit) csInfo).RadiansPerUnit;
                inchesPerUnit = AzukiMapSettings.INCHES_PER_DEGREES;
            }

            return inchesPerUnit;
        }
    }
}